#include "EndConnectOriDestHandler.h"
#include "StringHelper.h"
#include "EndOriDestSendHandler.h"
#include "StringHelper.h"
#include "Log.h"

using namespace std;
using namespace log4cplus;

Logger EndConnectOriDestHandler::log=GetLogger(LOG4CPLUS_TEXT("EndConnectOrDestHandler"));

void EndConnectOriDestHandler::GetSendInfo(ClientContext &client,SOCKET *sendSock,OVERLAPPED **sendOvl)
{
	*sendSock=client.DestSock();
	*sendOvl=client.OVL();
	LOG4CPLUS_DEBUG_STR(log,LOG4CPLUS_TEXT("Set http request data(original server) send info."));
}

ITransHandler* EndConnectOriDestHandler::GetNextHandler()
{
	return new EndOriDestSendHandler();
}

ITransHandler::ExecuteResultCode EndConnectOriDestHandler::OnExecuteError(ClientContext &client,OVERLAPPED *ovl,ITransHandler::ExecuteResultCode executeResult)
{
	return executeResult;
}

string* EndConnectOriDestHandler::AssemblyHttpRequest(ClientContext &client)
{
	bool connectFieldSetted=false;
	HttpRequestPack &request=client.HttpRequest();
	size_t bodySize=0;
	string *requestStr=new string();
	requestStr->append(request.Type());
	requestStr->append(" ");
	if(request.Type()=="CONNECT")
	{
		string str=StringHelper::ToString(request.ServerPort());
		requestStr->append(request.ServerName());
		requestStr->append(":");
		requestStr->append(str);
	}
	else
	{
		requestStr->append(request.Path());
	}
	requestStr->append(" ");
	requestStr->append(request.Version());
	requestStr->append("\r\n");
	for(map<string,string>::const_iterator i=request.Headers().begin();i!=request.Headers().end();++i)
	{
		if(StringHelper::StartWithA(i->first,"Proxy-"))
		{
			continue;
		}
		if(StringHelper::StartWithA(i->first,"Connection:"))
		{
			requestStr->append("Connection: close\r\n");
			connectFieldSetted=true;
			continue;
		}
		if(StringHelper::StartWithA(i->first,"Content-Length:"))
		{
			bodySize = atol(i->second.c_str());
		}
		requestStr->append(i->first);
		requestStr->append(":");
		requestStr->append(i->second);
		requestStr->append("\r\n");
	}
	if(!connectFieldSetted)
	{
		requestStr->append("Connection: close\r\n");
	}
	requestStr->append("\r\n");
	if(bodySize>0)
	{
		requestStr->append(request.Body(),bodySize);
		requestStr->append("\r\n");
	}
	return requestStr;
}

WSABUF* EndConnectOriDestHandler::FillBufferWithHttpRequest(ClientContext &client,std::string *requestStr)
{
	client.HttpRequest().SetTempBuffer(requestStr);
	if(requestStr->size()>client.Buffer()->len)
	{
		memcpy_s(client.Buffer()->buf,client.Buffer()->len,requestStr->c_str(),client.Buffer()->len);
		client.WeakRefBuffer()->buf=client.Buffer()->buf;
		client.WeakRefBuffer()->len=client.Buffer()->len;
		client.SetPartialTransIndex(client.Buffer()->len);
	}
	else
	{
		memcpy_s(client.Buffer()->buf,client.Buffer()->len,requestStr->c_str(),requestStr->size());
		client.WeakRefBuffer()->buf=client.Buffer()->buf;
		client.WeakRefBuffer()->len=requestStr->size();
		client.SetPartialTransIndex(0);
	}
	return client.WeakRefBuffer();
}